use smcrypto::sm4;
use hex;

//todo-ltq 如果udf中使用的话，不符合规则的参数调用加解密的话，结果集直接返回Option::None

/// SM4 ECB模式加密，返回hex字符串
pub fn sm4_ecb_encrypt(key: &[u8], data: &[u8]) -> String {
    let sm4_ecb = sm4::CryptSM4ECB::new(key);
    let encrypted = sm4_ecb.encrypt_ecb(data);
    hex::encode(encrypted)
}

/// SM4 ECB模式解密，入参为hex字符串
pub fn sm4_ecb_decrypt(key: &[u8], hex_data: &str) -> Vec<u8> {
    let sm4_ecb = sm4::CryptSM4ECB::new(key);
    let encrypted = hex::decode(hex_data).expect("Invalid hex string");
    sm4_ecb.decrypt_ecb(&encrypted)
}

/// SM4 CBC模式加密，返回hex字符串
pub fn sm4_cbc_encrypt(key: &[u8], iv: &[u8], data: &[u8]) -> String {
    let sm4_cbc = sm4::CryptSM4CBC::new(key, iv);
    let encrypted = sm4_cbc.encrypt_cbc(data);
    hex::encode(encrypted)
}

/// SM4 CBC模式解密，入参为hex字符串
pub fn sm4_cbc_decrypt(key: &[u8], iv: &[u8], hex_data: &str) -> Vec<u8> {
    let sm4_cbc = sm4::CryptSM4CBC::new(key, iv);
    let encrypted = hex::decode(hex_data).expect("Invalid hex string");
    sm4_cbc.decrypt_cbc(&encrypted)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_sm4_ecb_encrypt_decrypt() {
        let key = b"0123456789abcdef";
        let data = "中文Hello, SM4 ECB!123".as_bytes(); // 16字节对齐
        let encrypted_hex = sm4_ecb_encrypt(key, data);
        let decrypted = sm4_ecb_decrypt(key, &encrypted_hex);
        let clearText = String::from_utf8_lossy(&decrypted).to_string();
        println!("密文:{:?}",encrypted_hex);
        println!("明文:{:?}",clearText);
    }

    #[test]
    fn test_sm4_cbc_encrypt_decrypt() {
        let key = b"0123456789abcdef";
        let iv = b"abcdef9876543210";
        let data = b"Hello, SM4 CBC!123"; // 16字节对齐
        let encrypted_hex = sm4_cbc_encrypt(key, iv, data);
        let decrypted = sm4_cbc_decrypt(key, iv, &encrypted_hex);
        assert_eq!(decrypted, data);
    }
}